package com.miyi.core;

import java.io.File;
import java.io.IOException;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.json.JSONArray;
import org.json.JSONObject;

import com.google.gson.Gson;

import spark.Request;
import spark.Response;
import spark.Spark;

public abstract class Controller {
	public Request request;
	public Response response;
	private String defaultActionName = "index";
	private String defaultModuleName = "index";
	private static final String encoding = "utf-8";
	private static final String contentType = "text/html; charset=" + encoding;
	private String moduleName = defaultModuleName;
	private String actionName = defaultActionName;
	private boolean withSession = true;
	public void init(Request request, Response response){
		this.request = request;
		this.response = response;
		this.parsePath();
		
		if(withSession){
			this.request.session(true); 
		}
	}
	
	public PValidateConfig getValidateConfig(){
		return PValidateConfig.getInstance();
	}
	
	public void deInit(){
//		DBUtil.close();
//		if(persist!=null)
//			persist=null;
//		PHttpClient.getInstance().close();
	}
	
	private void parsePath(){
		String[] pathList = request.pathInfo().split("/");
		if(pathList.length>2){
			moduleName = pathList[1];
			actionName = pathList[2];
		}else if(pathList.length>1){
			moduleName = pathList[1];
		}
	}
	
	// ->  "/bar"
	public void redirect(String loction){
		response.redirect(loction);
	}
	
	// ->  "/bar",301
	public void redirect(String loction, int httpStatusCode){
		response.redirect(loction, httpStatusCode);
	}
	
	// POST  GET
	public String httpMethod(){
		return this.request.requestMethod();
	}
	
	public String getModuleName(){
		return moduleName;
	}
	
	public String getActionName(){
		return actionName;
	}
	
//	private VelocityEngine velocityEngine;
	Map<String, Object> modelMap = new HashMap<>();;
	
    /**
     * Constructor
     */
    public Controller() {
        //modelMap = new HashMap<>();
    }

    public void print(Object x){
    	System.out.println(x);
    }
    public void assign(String key,Object value){
    	modelMap.put(key, value);
    }

    public void display(){
    	display(this.actionName+".html");
    }
    
    public void error(String body){
    	this.assign("body", body);
    	this.halt(getTemplateContext("../error.html"));
    }
    
    public void success(String title){
    	render(title);
    }
    
    public void fatal(String message){
    	throw new FatalException(message);
    }
    
    public void halt(String message){
    	Spark.halt(message);
    }
    public String getTemplateContext(String templateName){
    	Template template = VelocityHelper.getInstance()
    			.getTemplate(this.getModuleName()+File.separator+templateName, encoding);
        VelocityContext context = new VelocityContext(modelMap);
        StringWriter writer = new StringWriter();
        template.merge(context, writer);
        String data = writer.toString();
        try {
			writer.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
        return data;
    }
    
    
    private void assignSession(){
    	Map<String,Object> sessionMap = new HashMap<String,Object>();
    	request.session().attributes().stream().forEach((key) -> {
    		sessionMap.put(key, request.session().attribute(key));
    	});
    	this.assign("session", sessionMap);
    }
    
    public void display(String templateName){
    	if(withSession)this.assignSession();
    	render(getTemplateContext(templateName));
    	
//    	Template template = VelocityHelper.getInstance()
//    			.getTemplate(this.getModuleName()+File.separator+templateName, encoding);
//        VelocityContext context = new VelocityContext(modelMap);
//        StringWriter writer = new StringWriter();
//        template.merge(context, writer);
//        render(writer);
//        
//        try {
//			writer.close();
//		} catch (IOException e) {
//			// TODO Auto-generated catch block
//			e.printStackTrace();
//		}
        
//      PrintWriter writer = null;
//		try {
//			response.header("Content-Type", contentType);
//			writer = this.response.raw().getWriter();
//	        template.merge(context, writer);
//	        writer.flush();
//		} catch (IOException e) {
//			e.printStackTrace();
//		} finally {
//			if (writer != null)
//	    		writer.close();
//		}

		
    }
    
    public String _get(String name){
    	return request.queryParams(name);
    }
    public String _get(String name,String defaultValue){
    	String result = request.queryParams(name);
		return result != null && !"".equals(result) ? result : defaultValue;
    }
    public long _get(String name,long defaultValue){
    	String result = request.queryParams(name);
    	return result != null && !"".equals(result) ? Long.parseLong(result) : defaultValue;
    }
    public String _post(String name){
    	return request.queryParams(name);
    }
    public String _post(String name,String defaultValue){
    	String result = request.queryParams(name);
		return result != null && !"".equals(result) ? result : defaultValue;
    }
    public long _post(String name,long defaultValue){
    	String result = request.queryParams(name);
    	return result != null && !"".equals(result) ? Long.parseLong(result) : defaultValue;
    }

	public String queryParams(String name) {
		return request.queryParams(name);
	}
	

	public String queryParams(String name, String defaultValue) {
		String result = request.queryParams(name);
		return result != null && !"".equals(result) ? result : defaultValue;
	}
	
	public long queryParams(String name, long defaultValue) {
		String result = request.queryParams(name);
		return result != null && !"".equals(result) ? Long.parseLong(result) : defaultValue;
	}

	
	public void render(StringWriter writer){
		response.header("Content-Type", contentType);
		response.body(writer.toString());
	}
	
	public void render(String str){
		response.header("Content-Type", contentType);
		response.body(str==null?"":str);
	}
	
	public void render(long val){
		response.header("Content-Type", contentType);
		response.body(String.valueOf(val));
	}
	
	public void render(int val){
		response.header("Content-Type", contentType);
		response.body(String.valueOf(val));
	}
	
	public void render(){
		response.header("Content-Type", contentType);
		response.body("");
	}
	
	public void renderJSON(Object obj){
		response.header("Content-Type", contentType);
		response.body(new Gson().toJson(obj));
	}
	
	public Object formatJson(Object obj) {
		
		return new Gson().toJson(obj);
	}
}
